/*package org.fastsyncer.parser.convert;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.SearchControls;

import org.apache.commons.lang.StringUtils;
import org.fastsyncer.common.entity.LdapConfig;
import org.fastsyncer.connector.ldap.LdapConnector;
import org.junit.Before;
import org.junit.Test;
import org.springframework.ldap.CommunicationException;
import org.springframework.ldap.core.ContextMapper;
import org.springframework.ldap.core.DirContextAdapter;
import org.springframework.ldap.core.LdapTemplate;

public class LdapAPI {

    private LdapTemplate ldapTemplate;

    private LdapConfig c;

    public String[] extendObjects;

    @Before
    public void init() {
        // 执行新增
        c = new LdapConfig();
        c.setUrl("ldap://10.238.218.227:389/");
        c.setBase("ou=aostar,dc=cts,dc=com");
        c.setDn("ou");
        c.setUserDn("cn=admin,dc=cts,dc=com");
        c.setPassword("admin");
        extendObjects = new String[] { "top", "organizationalUnit" };
        try {
            ldapTemplate = LdapConnector.getInstance().getLdapTemplate(c);
        } catch (CommunicationException e) {
            e.printStackTrace();
        } catch (NamingException e) {
            e.printStackTrace();
        }
    }

    private String _dn = "_dn";
    
    @Test
    public void reDnNameTree() {
        String dn = "ou";
        
        // 需求:修改某个节点名称
        String oldName = "中电启明星555";
        String newName = "中电启明星555666";
        
        // ou=中电启明星
        String oldDn = new StringBuilder(dn).append("=").append(oldName).toString();
        
        // 1.获取修改的节点和所有子节点
        List<Map<String, Object>> oldNodes = this.queryTree(ldapTemplate, oldDn);
        if(null == oldNodes || oldNodes.isEmpty()){
            return;
        }
        
        // 2.转换新节点和子节点
        List<Map<String, Object>> newNodes = this.convert(oldNodes, dn, newName);
        
        // 3.创建新节点和子节点
        System.out.println("创建新节点和子节点------end");
        int size = newNodes.size();
        Map<String, Object> row;
        LdapConnector conn = LdapConnector.getInstance();
        for (int i = 0; i < size; i++) {
            row = newNodes.get(i);
            // 3.1设置域 cn=ae86,ou=scdl,dc=aostar,dc=com
            // 在2.0版本推荐:DirContextAdapter是使用LDAP属性非常有用的工具，特别是添加或修改数据时。
            DirContextAdapter ctx = new DirContextAdapter(String.valueOf(row.get(_dn)));
            // 移除多余的属性
            row.remove(_dn);

            // 3.2转换基本属性名称和值类型
            this.convertAttrAdd(ctx, row);

            // 3.3绑定
            ldapTemplate.bind(ctx);
            conn.close(ctx);
        }
        
        // 4.删除修改的节点和子节点
        System.out.println("\r删除旧的节点和子节点------end");
        size -= 1;
        for (int i = size; i > -1; i--) {
            row = oldNodes.get(i);
            // 解除绑定
            ldapTemplate.unbind(String.valueOf(row.get(_dn)));
        }
        
        newNodes = null;
        oldNodes = null;
    }

    private List<Map<String, Object>> convert(List<Map<String, Object>> oldNodes, String dn, String orgName) {
        int size = oldNodes.size();
        List<Map<String, Object>> newNodes = new ArrayList<Map<String,Object>>(size);
        
        // ou=中电启明星666
        String nodeDn = new StringBuilder(dn).append("=").append(orgName).toString();
        Map<String, Object> row;
        String oldDn;
        String newDn;
        for (int i = 0; i < size; i++) {
            row = new HashMap<>();
            // 复制旧节点
            row.putAll(oldNodes.get(i));
            // 获取旧dn,ou=星盾,ou=中电启明星
            oldDn = String.valueOf(row.get(_dn));
            // 判断是否有层级
            if(oldDn.contains(",")){
                newDn = new StringBuilder(oldDn.substring(0, oldDn.lastIndexOf(","))).append(",").append(nodeDn).toString();
            }else{
                newDn = nodeDn;
            }
            // 创建新dn
            // row.put("ou=星盾,ou=中电启明星", "ou=星盾,ou=中电启明星666");
            row.put(_dn, newDn);
            
            // 应为修改的节点名称正好是第一条
            if(i==0){
                row.put("ou", orgName);
                row.put("cn", orgName);
                newNodes.add(row);
                continue;
            }
            newNodes.add(row);
        }
        
        newDn = null;
        oldDn = null;
        row = null;
        return newNodes;
    }

    private List<Map<String, Object>> queryTree(LdapTemplate ldapTemplate, String dn) {
        if(StringUtils.isBlank(dn)){
            return null;
        }

        *//**
         * 0:OBJECT_SCOPE,搜索指定的命名对象。 <br />
         * 1:ONELEVEL_SCOPE,只搜索指定命名对象的一个级别，这是缺省值。<br />
         * 2:SUBTREE_SCOPE,搜索以指定命名对象为根结点的整棵树,就像递归查询
         **//*
        SearchControls controls = new SearchControls();
        controls.setSearchScope(SearchControls.SUBTREE_SCOPE);
        
        ContextMapper<Map<String, Object>> contextMapper = new ContextMapper<Map<String, Object>>() {

            @Override
            public Map<String, Object> mapFromContext(Object ctx) throws javax.naming.NamingException {
                DirContextAdapter c = (DirContextAdapter) ctx;
                
                Attributes attrs = c.getAttributes();
                Map<String, Object> r = new HashMap<String, Object>();
                NamingEnumeration<String> iDs = attrs.getIDs();
                String key;
                Attribute attr;
                Object[] v;
                int size;
                while (iDs.hasMoreElements()) {
                    key = (String) iDs.nextElement();
                    attr = attrs.get(key);

                    size = attr.size();
                    // 单个值
                    if (1 == size) {
                        r.put(key, attr.get());
                        continue;
                    }

                    // 多个值
                    v = new Object[size];
                    for (int i = 0; i < size; i++) {
                        v[i] = attr.get(i);
                    }
                    r.put(key, v);
                }
                // 获取全路径dn
                r.put(_dn, c.getDn());
                return r;
            }
        };

        return ldapTemplate.search(dn.toString(), "(objectClass=*)", controls, contextMapper);
    }

    private void convertAttrAdd(DirContextAdapter ctx, Map<String, Object> row) {
        String k;
        Object v;
        for (Map.Entry<String, Object> obj : row.entrySet()) {
            k = obj.getKey();
            v = obj.getValue();
            // 如果是数组
            if(v instanceof Object[]){
                ctx.setAttributeValues(k, (Object[]) v, true);
                continue;
            }
            // 目标源名称
            ctx.addAttributeValue(k, String.valueOf(v));
        }
        k = null;
        v = null;
        row = null;
    }
    
}
*/